Newer
Older
taehui / taehui-fe / src / app / [language] / commentary / components / CommentaryItem.tsx
@Taehui Taehui on 6 Apr 3 KB 2024-04-07 오전 8:25
import usePutCommentary from "@/app/[language]/commentary/query/usePutCommentary";
import useWipeCommentary from "@/app/[language]/commentary/query/useWipeCommentary";
import { GetCommentaryAPI } from "@/type/wwwAPI";
import { useTranslations } from "next-intl";
import { useState } from "react";
import { PencilFill, TrashFill } from "react-bootstrap-icons";
import Button from "react-bootstrap/Button";
import ButtonGroup from "react-bootstrap/ButtonGroup";
import Col from "react-bootstrap/Col";
import FormControl from "react-bootstrap/FormControl";
import InputGroup from "react-bootstrap/InputGroup";
import InputGroupText from "react-bootstrap/InputGroupText";
import Row from "react-bootstrap/Row";
import Stack from "react-bootstrap/Stack";
import ReactTextareaAutosize from "react-textarea-autosize";
import { toast } from "react-toastify";
import { getDatetime } from "taehui-ts/date";

export default function CommentaryItem({
  commentary: { commentaryID, avatarName, text, date },
}: {
  commentary: GetCommentaryAPI[number];
}) {
  const t = useTranslations();

  const [isModifyOpened, setModifyOpened] = useState(false);
  const [avatarCipher, setAvatarCipher] = useState("");
  const [textInput, setTextInput] = useState("");

  const { mutateAsync: wipeCommentary } = useWipeCommentary();
  const { mutateAsync: putCommentary } = usePutCommentary();

  if (isModifyOpened) {
    return (
      <Row>
        <Stack gap={2}>
          <InputGroup>
            <InputGroupText>{avatarName}</InputGroupText>
            <FormControl
              as={ReactTextareaAutosize}
              value={textInput}
              isValid={!!textInput}
              isInvalid={!textInput}
              placeholder={t("text")}
              onChange={({ target: { value } }) => setTextInput(value)}
            />
            <InputGroupText suppressHydrationWarning>
              {getDatetime(date)}
            </InputGroupText>
          </InputGroup>
          <InputGroup>
            <InputGroupText>{t("avatarCipher")}</InputGroupText>
            <FormControl
              type="password"
              value={avatarCipher}
              isInvalid={!avatarCipher}
              placeholder={t("avatarCipher")}
              onChange={({ target: { value } }) => setAvatarCipher(value)}
            />
            <Button
              variant="warning"
              onClick={async () => {
                if (avatarCipher && textInput) {
                  await putCommentary({
                    commentaryID,
                    avatarCipher,
                    text: textInput,
                  });
                  setModifyOpened(false);
                } else {
                  toast.error(t("failedValidation"));
                }
              }}
            >
              <PencilFill />
            </Button>
          </InputGroup>
        </Stack>
      </Row>
    );
  }

  const isLoading = !(commentaryID >= 0);

  return (
    <Row className="flex-nowrap">
      <Col xs="auto">{avatarName}</Col>
      <Col className="cc">
        <span>{text}</span>
      </Col>
      <Col xs="auto">
        <Stack gap={2}>
          {getDatetime(date)}
          <ButtonGroup>
            <Button
              disabled={isLoading}
              variant="warning"
              onClick={() => {
                setTextInput(text);
                setModifyOpened(true);
              }}
            >
              <PencilFill />
            </Button>
            <Button
              disabled={isLoading}
              variant="danger"
              onClick={async () => {
                if (avatarCipher) {
                  await wipeCommentary({ commentaryID, avatarCipher });
                } else {
                  toast.error(t("failedValidation"));
                }
              }}
            >
              <TrashFill />
            </Button>
          </ButtonGroup>
        </Stack>
      </Col>
    </Row>
  );
}